Week3-Three-Tier-Architecture
Week 3: 3-Tier 아키텍처 (Web/WAS 분리)
Apache 웹 서버와 Tomcat WAS를 분리한 확장 가능한 3계층 아키텍처

아키텍처 개요
인터넷 사용자
↓ HTTP 요청
Internet Gateway
↓
VPC (10.0.0.0/16)
├── Public Subnet (10.0.1.0/24)
│ └── EC2 (Apache Web Server)
│ ├── 정적 파일 처리
│ ├── 프록시 서버
│ └── SSL 터미네이션
├── Private Subnet (10.0.2.0/24)
│ └── EC2 (Tomcat WAS)
│ ├── JSP/Servlet 처리
│ ├── 비즈니스 로직
│ └── 세션 관리
└── Private Subnet (10.0.3.0/24)
└── RDS MySQL
├── 데이터 저장
└── 트랜잭션 처리
상세 네트워크 아키텍처
VPC 설계 (확장)
VPC: webapp-vpc (10.0.0.0/16)
│
├── Internet Gateway: webapp-igw
│
├── Public Subnet: webapp-public-subnet
│ ├── CIDR: 10.0.1.0/24
│ ├── AZ: ap-northeast-2a
│ └── 용도: Web Server (Apache)
│
├── Private Subnet: webapp-private-subnet-app
│ ├── CIDR: 10.0.2.0/24
│ ├── AZ: ap-northeast-2a
│ └── 용도: WAS Server (Tomcat)
│
└── Private Subnet: webapp-private-subnet-db
├── CIDR: 10.0.3.0/24
├── AZ: ap-northeast-2a
└── 용도: Database (RDS)
보안 그룹 설계
webapp-web-sg (Web Server):
├── HTTP (80) ← 0.0.0.0/0
├── HTTPS (443) ← 0.0.0.0/0
├── SSH (22) ← My IP
└── Outbound: All
webapp-was-sg (WAS Server):
├── HTTP (8080) ← webapp-web-sg
├── AJP (8009) ← webapp-web-sg
├── SSH (22) ← webapp-web-sg
└── Outbound: All
webapp-db-sg (Database):
├── MySQL (3306) ← webapp-was-sg
└── Outbound: None
계층별 상세 구성
1. 웹 서버 계층 (Apache HTTP Server)
역할과 책임:
✅ 정적 콘텐츠 서비스 (HTML, CSS, JS, 이미지)
✅ SSL/TLS 터미네이션 및 보안
✅ 동적 요청을 WAS로 프록시
✅ 로드 밸런싱 (향후 다중 WAS 대비)
✅ 압축 및 캐싱
Apache 설정:
# /etc/httpd/conf/httpd.conf 주요 설정
DocumentRoot "/var/www/html/webapp"
DirectoryIndex index.html index.jsp
# 정적 파일 처리
<Directory "/var/www/html/webapp">
Options -Indexes +FollowSymLinks
AllowOverride None
Require all granted
</Directory>
# JSP 파일을 Tomcat으로 프록시
ProxyPass /webapp/*.jsp http://10.0.2.x:8080/webapp/
ProxyPassReverse /webapp/*.jsp http://10.0.2.x:8080/webapp/
# 동적 경로를 Tomcat으로 프록시
ProxyPass /webapp/api/ http://10.0.2.x:8080/webapp/api/
ProxyPassReverse /webapp/api/ http://10.0.2.x:8080/webapp/api/
디렉토리 구조:
/var/www/html/webapp/
├── index.html (정적 메인 페이지)
├── css/
│ └── style.css
├── js/
│ └── app.js
├── images/
│ └── logo.png
└── api/ (프록시로 Tomcat 전달)
2. WAS 서버 계층 (Apache Tomcat)
역할과 책임:
✅ JSP/Servlet 실행 및 컴파일
✅ 세션 관리 및 상태 유지
✅ 데이터베이스 연결 풀 관리
✅ 비즈니스 로직 처리
✅ API 엔드포인트 제공
Tomcat 설정:
<!-- server.xml 주요 설정 -->
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
<Connector protocol="AJP/1.3"
address="0.0.0.0"
port="8009"
redirectPort="8443" />
<Context path="/webapp"
docBase="/opt/tomcat/webapps/webapp"
reloadable="true" />
웹 애플리케이션 구조:
/opt/tomcat/webapps/webapp/
├── WEB-INF/
│ ├── web.xml (배포 설정)
│ ├── lib/
│ │ └── mysql-connector-java.jar
│ └── classes/
│ └── Database.class
├── index.jsp (동적 메인 페이지)
├── users.jsp (사용자 관리)
├── api/
│ ├── users.jsp (REST API)
│ └── health.jsp (헬스체크)
└── META-INF/
└── context.xml (DB 연결 설정)
요청 처리 흐름
정적 콘텐츠 요청
1. 사용자: GET /webapp/css/style.css
2. Apache: 로컬 파일 시스템에서 직접 서비스
3. 응답: CSS 파일 (캐시 헤더 포함)
처리 시간: ~10-50ms
부하: Web 서버만 관여, WAS/DB 무관
동적 콘텐츠 요청
1. 사용자: GET /webapp/users.jsp
2. Apache: JSP 요청 감지 → Tomcat으로 프록시
3. Tomcat: JSP 컴파일 및 실행
4. Database: 사용자 데이터 조회
5. Tomcat: HTML 생성 후 Apache로 응답
6. Apache: 클라이언트에게 최종 응답
처리 시간: ~100-500ms
부하: 모든 계층 관여
성능 최적화
Apache 최적화
# 압축 설정
LoadModule deflate_module modules/mod_deflate.so
<Location "/webapp">
SetOutputFilter DEFLATE
SetEnvIfNoCase Request_URI \
\.(?:gif|jpe?g|png)$ no-gzip dont-vary
</Location>
# 캐싱 설정
LoadModule expires_module modules/mod_expires.so
<Directory "/var/www/html/webapp">
ExpiresActive On
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType image/png "access plus 1 year"
</Directory>
Tomcat 최적화
# catalina.sh JVM 설정
export JAVA_OPTS="-Xms512m -Xmx1024m -XX:MetaspaceSize=256m"
export CATALINA_OPTS="-server -Djava.awt.headless=true"
# 연결 풀 최적화 (context.xml)
<Resource name="jdbc/webapp"
auth="Container"
type="javax.sql.DataSource"
maxActive="20"
maxIdle="10"
maxWait="10000"
username="webapp_user"
password="password"
driverClassName="com.mysql.cj.jdbc.Driver"
url="jdbc:mysql://rds-endpoint:3306/webapp_db"/>
데이터베이스 최적화
-- MySQL 설정 최적화
SET GLOBAL innodb_buffer_pool_size = 128M;
SET GLOBAL max_connections = 100;
SET GLOBAL query_cache_size = 32M;
-- 슬로우 쿼리 로그 활성화
SET GLOBAL slow_query_log = 1;
SET GLOBAL long_query_time = 2;
모니터링 및 로그
Apache 로그
# 액세스 로그
/var/log/httpd/access_log
# 에러 로그
/var/log/httpd/error_log
# 로그 포맷 (Combined Log Format)
%h %l %u %t "%r" %>s %O "%{Referer}i" "%{User-Agent}i"
Tomcat 로그
# 애플리케이션 로그
/opt/tomcat/logs/catalina.out
# 액세스 로그
/opt/tomcat/logs/localhost_access_log.txt
# 애플리케이션별 로그
/opt/tomcat/logs/webapp.log
보안 강화
Apache 보안 설정
# 서버 정보 숨김
ServerTokens Prod
ServerSignature Off
# 디렉토리 브라우징 비활성화
Options -Indexes
# 위험한 HTTP 메소드 차단
<LimitExcept GET POST HEAD>
Require all denied
</LimitExcept>
# 보안 헤더 추가
Header always set X-Content-Type-Options nosniff
Header always set X-Frame-Options DENY
Header always set X-XSS-Protection "1; mode=block"
Tomcat 보안 설정
<!-- server.xml 보안 설정 -->
<Connector port="8080" protocol="HTTP/1.1"
server="Apache"
secure="true"
maxPostSize="1048576" />
<!-- 관리 기능 비활성화 -->
<Host name="localhost" appBase="webapps"
autoDeploy="false"
deployOnStartup="false" />
성능 벤치마크
처리 능력 비교
Week 2 (Node.js 단일):
├── 동시 접속: ~100명
├── 응답 시간: 200-500ms
└── 처리량: ~100 req/sec
Week 3 (Web/WAS 분리):
├── 동시 접속: ~200-300명
├── 응답 시간: 150-400ms
├── 처리량: ~200 req/sec
└── 정적 파일: ~50ms (큰 개선)
리소스 사용량
Web 서버 (Apache):
├── CPU: 10-30%
├── 메모리: ~200MB
└── 주요 역할: 정적 파일, 프록시
WAS 서버 (Tomcat):
├── CPU: 20-60%
├── 메모리: ~600MB
└── 주요 역할: JSP 컴파일, 비즈니스 로직
장점과 개선점
Week 2 대비 개선점
✅ 역할 분담으로 성능 향상
├── 정적 파일: Apache가 직접 처리 (빠름)
└── 동적 파일: Tomcat이 전담 처리
✅ 확장성 향상
├── Web 서버와 WAS 독립적 확장 가능
└── 향후 다중 WAS 구성 기반 마련
✅ 보안 강화
├── WAS가 Private 서브넷에 격리
└── 계층별 세분화된 보안 그룹
✅ 유지보수성 향상
├── 각 계층별 독립적 관리
└── 장애 발생 시 영향 범위 최소화
여전한 한계점
❌ 단일 인스턴스 의존 (SPOF)
❌ 수동 확장 (Auto Scaling 없음)
❌ 고가용성 부족 (Single AZ)
❌ 로드 밸런싱 없음
❌ 장애 복구 자동화 없음
실제 운영 시나리오
정상 운영 시
사용자 요청 → Apache → 정적 파일 즉시 응답
사용자 요청 → Apache → Tomcat → DB → 응답
응답 시간: 평균 200ms
동시 처리: 200명
가용성: 99.5%
장애 시나리오
Web 서버 장애:
├── 전체 서비스 중단
└── 복구까지 서비스 불가
WAS 서버 장애:
├── 동적 페이지만 중단
├── 정적 파일은 계속 서비스
└── 수동 재시작 필요
DB 장애:
├── 전체 동적 기능 중단
└── RDS 자동 복구 대기
Week 3.5로의 발전 방향
해결해야 할 문제
1. 단일 장애점 (SPOF) 제거
→ Multi-AZ 구성
2. 자동 확장 구현
→ Auto Scaling Group
3. 트래픽 분산
→ Application Load Balancer
4. 고가용성 확보
→ Multi-AZ RDS
Week 3 완성: 확장 가능한 3-Tier 아키텍처 구축 완료
다음 단계: AWS EDU/Archive/조선대학교 AWS 멘토링/Edu Architecture/Week3.5-HA-Scalable-Architecture - 고가용성 및 자동 확장으로 업그레이드